package com.thm.tfast.modules.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.thm.tfast.core.enums.DeleteFlagEnum;
import com.thm.tfast.core.exception.Asserts;
import com.thm.tfast.core.sevruity.domain.SysUserDetails;
import com.thm.tfast.core.utils.SecurityUtil;
import com.thm.tfast.modules.sys.mapper.SysDictMapper;
import com.thm.tfast.modules.sys.model.SysDict;
import com.thm.tfast.modules.sys.model.SysDictItem;
import com.thm.tfast.modules.sys.model.dto.dict.DictInsertDto;
import com.thm.tfast.modules.sys.model.dto.dict.DictUpdateDto;
import com.thm.tfast.modules.sys.service.SysDictItemService;
import com.thm.tfast.modules.sys.service.SysDictService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * <p>
 * 字典信息表 服务实现类
 * </p>
 *
 * @author THM
 * @since 2022-10-31
 */
@Service
public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> implements SysDictService {

    @Resource
    private SysDictItemService sysDictItemService;

    @Override
    public Page<SysDict> page(String keyword, Integer pageNum, Integer pageSize) {
        Page<SysDict> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<SysDict> wrapper = Wrappers.lambdaQuery();
        if (StrUtil.isNotEmpty(keyword)) {
            wrapper.like(SysDict::getType, keyword)
                    .or()
                    .like(SysDict::getName, keyword);
        }
        wrapper.ne(SysDict::getDelFlag, DeleteFlagEnum.DELETED.getCode());
        return this.page(page, wrapper);
    }

    @Override
    @Transactional
    public Long insert(DictInsertDto dto) {
        SysDict sysDict = this.getOne(Wrappers
                .<SysDict>lambdaQuery()
                .eq(SysDict::getType, dto.getType()));
        if (Objects.nonNull(sysDict)){
            Asserts.fail("字典已经存在");
        }
        sysDict = BeanUtil.toBean(dto,SysDict.class);
        SysUserDetails currentUser = SecurityUtil.getCurrentUser();
        sysDict.setCreateUser(currentUser.getUserId());
        sysDict.setCreateTime(currentUser.getDate());
        sysDict.setUpdateUser(currentUser.getUserId());
        sysDict.setUpdateTime(currentUser.getDate());
        this.save(sysDict);
        return sysDict.getId();
    }

    @Override
    @Transactional
    public Boolean update(DictUpdateDto dto) {
        if (Objects.isNull(this.getById(dto.getId()))){
            Asserts.fail("字典信息不存在");
        }
        SysDict sysDict = this.getOne(Wrappers
                .<SysDict>lambdaQuery()
                .eq(SysDict::getType, dto.getType())
                .ne(SysDict::getId, dto.getId()));
        if (Objects.nonNull(sysDict)){
            Asserts.fail(dto.getType() + "字典已经存在");
        }
        sysDict = BeanUtil.toBean(dto, SysDict.class);
        //修改字典类型，同时修改字典项信息
        if (StrUtil.isNotEmpty(sysDict.getType())){
            sysDictItemService.update(Wrappers
                    .<SysDictItem>lambdaUpdate()
                    .set(SysDictItem::getType,sysDict.getType())
                    .eq(SysDictItem::getDictId,sysDict.getId()));
        }
        SysUserDetails currentUser = SecurityUtil.getCurrentUser();
        sysDict.setUpdateUser(currentUser.getUserId());
        sysDict.setUpdateTime(currentUser.getDate());
        //删除字典相关缓存
        sysDictItemService.delDictCache(sysDict.getType());
        return this.updateById(sysDict);
    }

    @Override
    @Transactional
    public Boolean delete(Long dictId) {
        SysDict sysDict = this.getById(dictId);
        if (Objects.isNull(sysDict)){
            Asserts.fail("字典信息不存在");
        }
        int count = sysDictItemService.count(Wrappers
                .<SysDictItem>lambdaQuery()
                .eq(SysDictItem::getDictId, dictId)
                .eq(SysDictItem::getDelFlag,DeleteFlagEnum.UNDELETE.getCode()));
        if (count != 0){
            Asserts.fail("存在字典项信息，不能删除字典信息");
        }
        SysUserDetails currentUser = SecurityUtil.getCurrentUser();
        sysDict.setUpdateUser(currentUser.getUserId());
        sysDict.setUpdateTime(currentUser.getDate());
        sysDict.setDelFlag(DeleteFlagEnum.DELETED.getCode());
        //删除与菜单相关缓存
        sysDictItemService.delDictCache(sysDict.getType());
        return this.updateById(sysDict);
    }
}
